package com.longkier.gx_library_springboot.Service;

import com.longkier.gx_library_springboot.repository.AdminRepository;
import com.longkier.gx_library_springboot.repository.BookAdminRepository;
import com.longkier.gx_library_springboot.repository.UserRepository;
import com.longkier.gx_library_springboot.entity.Admin;
import com.longkier.gx_library_springboot.entity.BookAdmin;
import com.longkier.gx_library_springboot.entity.User;
import com.longkier.gx_library_springboot.utils.RequestUtils;

import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

@Service
@RequiredArgsConstructor
public class LoginService {

    private static final Logger logger = LoggerFactory.getLogger(LoginService.class);

    private final AdminRepository adminRepository;
    private final BookAdminRepository bookAdminRepository;
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    /**
     * 处理用户登录请求。
     *
     * @param userType 用户类型（admin, book_admin, user）
     * @param username 用户名
     * @param password 密码
     * @return 返回登录结果的响应对象
     */
    public Map<String, Object> login(String userType, String username, String password) {
        // 检查用户类型是否为空或空字符串
        if (userType == null || userType.trim().isEmpty()) {
            return RequestUtils.buildResponse("用户名或密码错误", 403);
        }

        try {
            // 根据用户类型调用相应的登录处理方法
            return switch (userType.toLowerCase()) {
                case "admin" -> handleLogin(adminRepository::findByUsername, username, password);
                case "book_admin" -> handleLogin(this::findBookAdminByUsername, username, password);
                case "user" -> handleLogin(this::findUserByUsername, username, password);
                default -> RequestUtils.buildResponse("用户名或密码错误", 403);
            };
        } catch (Exception e) {
            // 捕获异常并返回错误响应
            logger.error("登录时发生异常: {}", e.getMessage(), e);
            return RequestUtils.buildResponse("登录时出错", 500);
        }
    }

    /**
     * 处理用户登录。
     */
    private <T> Map<String, Object> handleLogin(Function<String, Optional<T>> userFinder, String username, String password) {
        Optional<T> user = userFinder.apply(username);
        if (user.isPresent() && !checkStatus(user.get())) {
            return RequestUtils.buildResponse("账户已被禁用", 403);
        }
        return handleLoginWithValidation(user, password);
    }

    /**
     * 检查用户状态是否为0。
     */
    private boolean checkStatus(Object user) {
        if (user instanceof Admin) {
            return ((Admin) user).getStatus() != 0;
        } else if (user instanceof BookAdmin) {
            return ((BookAdmin) user).getStatus() != 0;
        } else if (user instanceof User) {
            return ((User) user).getStatus() != 0;
        }
        return true; // 默认情况下允许登录
    }

    /**
     * 处理图书管理员登录。
     */
    private Optional<BookAdmin> findBookAdminByUsername(String username) {
        Optional<BookAdmin> user = bookAdminRepository.findByUsername(username);
        if (user.isEmpty()) {
            user = bookAdminRepository.findByEmail(username);
        }
        return user;
    }

    /**
     * 处理普通用户登录。
     */
    private Optional<User> findUserByUsername(String username) {
        Optional<User> user = userRepository.findByUsername(username);
        if (user.isEmpty()) {
            try {
                String cardNumber = String.valueOf(Long.parseLong(username));
                user = userRepository.findByCardNumber(cardNumber);
            } catch (NumberFormatException e) {
                // 如果转换失败，则不处理
            }
        }
        return user;
    }

    /**
     * 处理用户验证，检查密码是否正确。
     */
    private <T> Map<String, Object> handleLoginWithValidation(@NotNull Optional<T> userOptional, String rawPassword) {
        if (userOptional.isPresent()) {
            T user = userOptional.get();

            // 检查密码是否匹配
            boolean isValidPassword = validateUser(user, rawPassword);
            if (isValidPassword) {
                return RequestUtils.buildResponse(user, 200);
            } else {
                return RequestUtils.buildResponse("用户名或密码错误", 401); // 未授权
            }
        } else {
            return RequestUtils.buildResponse("用户名或密码错误", 404); // 未找到
        }
    }

    /**
     * 验证用户密码的方法。
     *
     * @param user        用户实体
     * @param rawPassword 输入的密码
     * @return 密码是否正确
     */
    private boolean validateUser(Object user, String rawPassword) {
        String encodedPassword = null;

        // 根据不同的用户类型获取密码
        if (user instanceof Admin) {
            encodedPassword = ((Admin) user).getPassword();
        } else if (user instanceof BookAdmin) {
            encodedPassword = ((BookAdmin) user).getPassword();
        } else if (user instanceof User) {
            encodedPassword = ((User) user).getPassword();
        }

        // 使用 BCryptPasswordEncoder 验证密码
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }
}
